package tk.winshu.argumentresolver.resovler;

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import tk.winshu.argumentresolver.exception.RequestException;
import tk.winshu.argumentresolver.exception.UnLoginException;
import tk.winshu.argumentresolver.model.User;
import tk.winshu.argumentresolver.service.IUserService;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * @author Kevin
 * @since 2019/6/10
 */
public class CurrentUserResolver implements HandlerMethodArgumentResolver {

    private IUserService userService;

    public CurrentUserResolver(IUserService userService) {
        this.userService = userService;
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().isAssignableFrom(User.class)
                && methodParameter.hasParameterAnnotation(CurrentUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        if (request == null) {
            throw new IllegalArgumentException("request");
        }
        String jessionid = getJessionid(request);
        User user = userService.getUser(jessionid);
        if (user == null) {
            throw new UnLoginException();
        }
        return user;
    }

    public static String getJessionid(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            throw new RequestException();
        }
        for (Cookie cookie : request.getCookies()) {
            if ("JSESSIONID".equals(cookie.getName())) {
                return cookie.getValue();
            }
        }
        throw new RequestException();
    }
}
